package com.ruoyi.weixin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.weixin.Exception.BussnissExecption;
import com.ruoyi.weixin.anno.ILog;
import com.ruoyi.weixin.entity.*;
import com.ruoyi.weixin.mapper.AccountFamMapper;
import com.ruoyi.weixin.mapper.UserMapper;
import com.ruoyi.weixin.service.LoginLogService;
import com.ruoyi.weixin.service.SettingsService;
import com.ruoyi.weixin.service.UserService;
import com.ruoyi.weixin.untils.BaseContext;
import com.ruoyi.weixin.untils.JWTUtils;
import com.ruoyi.weixin.untils.MD5;
import com.ruoyi.weixin.untils.createCode;
import com.ruoyi.weixin.vo.RePassvO;
import com.ruoyi.weixin.vo.UserPassWord;
import com.ruoyi.weixin.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * (User)表服务实现类
 *
 * @author makejava
 * @since 2023-12-15 10:15:26
 */
@Service("userService")
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userInfoDao;

    @Value("${APPID}")
    private String appid;

    @Value("${APPSECRET}")
    private String appsecret;

    @Value("${token.expireTime}")
    private Integer expireTime;
    @Autowired
    private RestTemplate restTemplate;

    // 用于存储用户信息和token
    Map<String, Object> map = new HashMap<>();

    @Resource
    private LoginLogService loginLogService;

    @Autowired
    private JavaMailSenderImpl mailSender;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    SettingsService settingsService;

    @Autowired
    AccountFamMapper accountFamMapper;
    /**
     * 登录验证
     *
     * @param code 临时登录码
     * @return ·
     */
//    @ILog("一键登录")
    public Map<String, Object> checkLogin(String code, HttpServletRequest request) {
        // 根据传入code，调用微信服务器，获取唯一openid
        // 微信服务器接口地址
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + appsecret
                + "&js_code=" + code + "&grant_type=authorization_code";
        String errmsg = "";
        String errcode = "";
        String session_key = "";
        String openid = "";
        WeChatSessionModel weChatSessionModel;
        // 发送请求
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
        // 判断请求是否成功
        if (responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK) {
            // 获取主要内容
            String sessionData = responseEntity.getBody();
            Gson gson = new Gson();
            //将json字符串转化为实体类;
            weChatSessionModel = gson.fromJson(sessionData, WeChatSessionModel.class);
            log.info("返回的数据==>{}", weChatSessionModel);
            //获取用户的唯一标识openid
            openid = weChatSessionModel.getOpenid();
            //获取错误码
            errcode = weChatSessionModel.getErrcode();
            //获取错误信息
            errmsg = weChatSessionModel.getErrmsg();
            session_key = weChatSessionModel.getSession_key();

        } else {
            log.info("出现错误，错误信息：{}", errmsg);
            throw new BussnissExecption(errmsg);
        }
        // 判断是否成功获取到openid
        if ("".equals(openid) || openid == null) {
            log.info("错误获取openid,错误信息:{}", errmsg);
            throw new BussnissExecption(errmsg);
        } else {
            // 判断用户是否存在，查询数据库
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getOpenId, openid);
            User userInfo = super.getOne(queryWrapper);
            UserVo userVo = new UserVo();
            // 不存在，加入数据表
            if (userInfo == null) {
                // 填充初始信息
                String s = UUID.randomUUID().toString().substring(0, 5);
                User tempUserInfo = new User(null, "用户" + s,
                        "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F56fd66aa-d942-456c-b169-eaaddbc0c200%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1707727357&t=562910e85cdb00905072452ad5664642",
                        0, null, openid, null, null, session_key,5,"",null,null,null,new Date(),request.getRemoteAddr());

                // 加入数据表
                sentsEmail("sent",s);
                userInfoDao.insert(tempUserInfo);
                loginLog(tempUserInfo,request);
                Map<String, Object> map = resultMap(tempUserInfo);
                return map;
            } else {
                if (userInfo.getStatus()==0){
                    loginLog(userInfo,request);
                    // 存在，将用户信息加入map返回
                    userInfo.setIp(request.getRemoteAddr());
                    Map<String, Object> map = resultMap(userInfo);
                    return map;
                }else {
                    throw new BussnissExecption("账号被禁，请联系管理员");
                }
            }
        }
    }

    public void loginLog(User user,HttpServletRequest request) {
        System.err.println(user);
        System.err.println(request.getRemoteAddr());
        LoginLog loginLog = new LoginLog(null,request.getRemoteAddr(),user.getNickName(),new Date(),user.getId(),user.getRealName());
        loginLogService.save(loginLog);
    }

    public Map<String, Object> resultMap(User user){
        Map<String, Object> map = new HashMap<>();
        Integer famId=accountFamMapper.getFamId(user.getId());
        UserVo userVo = new UserVo();
        if (famId!=null){
            user.setFamId(famId);
        }
        BeanUtils.copyProperties(user,userVo);
        map.put("user", userVo);
        String token = JWTUtils.createToken(userVo.getId().toString());
        map.put("token", token);
        Settings settings = settingsService.getOne(new LambdaQueryWrapper<Settings>().eq(Settings::getUserId, user.getId()));
        if (settings==null){
            settings=settingsService.getById(1);
        }
        map.put("settings", settings);
        return map;
    }
    @Override
//    @ILog("账户密码登录")
    public Map<String, Object> checkLoginByPassword(UserPassWord userVo,HttpServletRequest request) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>();
        User user = super.getOne(queryWrapper.eq(User::getPhone, userVo.getPhone()));
        if (user == null) {
            throw new BussnissExecption("查无此人，请重新输入");
        }
        if (user.getStatus()!=0){
            throw new BussnissExecption("账号被禁，请联系管理员");
        }
        System.err.println(MD5.encrypt(userVo.getPassWord()));
        if (!user.getPassWord().equals(MD5.encrypt(userVo.getPassWord()))) {
            throw new BussnissExecption("密码错误，请重新输入");
        } else {
            loginLog(user,request);
            return resultMap(user);
        }
    }

    @Override
    public Object wenFindPassByda(UserVo userVo) {
        return null;
    }

    @Override
    public int sentEmail(String phone) {
        sentsEmail("find",phone);
        return 1;
    }

    @Override
    public R<?> checkCode(String code) {
        Object cacheObject = redisCache.getCacheObject("USER::FIND::CODE");
        System.err.println(cacheObject);
        if (cacheObject==null){
            throw new BussnissExecption("验证码失效");
        }

        if (!code.equals(cacheObject.toString())){
            redisCache.deleteObject("USER::FIND::CODE");
            throw new BussnissExecption("验证码错误");
        }
        redisCache.deleteObject("USER::FIND::CODE");
        return R.ok();
    }

    @Override
    public R<?> reSetPass(RePassvO rePassvO) {
        User one = super.getOne(new LambdaQueryWrapper<User>().eq(User::getPhone, rePassvO.getToken()));
        one.setPassWord(MD5.encrypt(rePassvO.getPassWord()));
        return R.ok(super.updateById(one));
    }


    public void sentsEmail(String type,String phone){
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        mailMessage.setFrom("1707997880@qq.com");
        if (type=="find"){
            User one = super.getOne(new LambdaQueryWrapper<User>().eq(User::getPhone, phone));
            if (one == null) {
                throw new BussnissExecption("用户不存在");
            }
            if (one.getEmail() != null) {
                mailMessage.setTo(one.getEmail());
            } else {
                mailMessage.setTo(phone+"@163.com");
            }
            String math = createCode.checkCode("MATH", 6);
            redisCache.setCacheObject("USER::FIND::CODE",math,30, TimeUnit.MINUTES);
            String s = redisCache.getCacheObject("USER::FIND::CODE").toString();
            System.err.println(s);
            mailMessage.setText("【煋玥阁】：邮箱验证码：" + math + "请尽快完成操作，若非本人操作，请忽略。");
            mailMessage.setSubject("验证码通知");
            mailSender.send(mailMessage);
            System.out.println("====完成发送！====");
        }else {
            ArrayList<String> list = new ArrayList<>();
            list.add("3012605304@qq.com");
            list.add("2119716366@qq.com");
            for (String s : list) {
                mailMessage.setTo(s);
                mailMessage.setText("【煋玥阁】："+phone +"用户,完成注册，请尽快完成操作，若非本人操作，请忽略。");
                mailMessage.setSubject("用户注册通知");
                mailSender.send(mailMessage);
                System.out.println("====完成发送！====");
            }

        }


    }
}
